﻿using SqlSugar;
using System.Dynamic;

namespace _5_NovaAdmin.Infrastructure.Persistence.Context;

/// <summary>
/// 数据库链接服务
/// </summary>
public static class DbContextSetup
{
    /// <summary>
    /// 注入数据库服务
    /// </summary>
    /// <param name="services"></param>
    /// <returns></returns>
    /// <exception cref="InvalidOperationException"></exception>
    public static void AddUseContext(this IServiceCollection services)
    {
        var config = services.BuildServiceProvider().GetRequiredService<IConfiguration>();
        var dbObject = config.GetSection("Db").GetChildren()
            .FirstOrDefault(c => bool.TryParse(c["Enabled"], out var enabled) && enabled);

        string dbType = dbObject?.Key ?? "MySql"; // 默认使用 MySql  
        string dbConn = dbObject?["dbconn"]
                        ?? throw new InvalidOperationException("未找到有效的数据库连接字符串");

        // 1. 注入 EF Core
        services.AddEfCore(dbType, dbConn);

        // 2. 注入 SqlSugar
        services.AddSqlSugar(dbType, dbConn);
    }

    /// <summary>
    /// 注入 EF Core
    /// </summary>
    /// <param name="services"></param>
    /// <param name="dbType"></param>
    /// <param name="dbConn"></param>
    /// <returns></returns>
    private static void AddEfCore(this IServiceCollection services, string dbType, string dbConn)
    {
        services.AddDbContext<AppDbContext>(options =>
        {
            _ = dbType switch
            {
                "SqlServer" => options.UseSqlServer(dbConn),
                "Oracle" => options.UseOracle(dbConn),
                "PostgreSql" => options.UseNpgsql(dbConn),
                "Sqlite" => options.UseSqlite(dbConn),
                _ => options.UseMySql(dbConn, ServerVersion.AutoDetect(dbConn)) // 默认 MySQL
            };
        });
    }

    /// <summary>
    /// 注入 SqlSugar
    /// </summary>
    /// <param name="services"></param>
    /// <param name="dbType"></param>
    /// <param name="dbConn"></param>
    /// <returns></returns>
    private static void AddSqlSugar(this IServiceCollection services, string dbType, string dbConn)
    {
        services.AddScoped<ISqlSugarClient>(provider =>
        {
            var db = new SqlSugarScope(new ConnectionConfig
            {
                ConnectionString = dbConn,
                DbType = dbType switch
                {
                    "SqlServer" => SqlSugar.DbType.SqlServer,
                    "Oracle" => SqlSugar.DbType.Oracle,
                    "PostgreSql" => SqlSugar.DbType.PostgreSQL,
                    "Sqlite" => SqlSugar.DbType.Sqlite,
                    _ => SqlSugar.DbType.MySql // 默认 MySQL
                },
                IsAutoCloseConnection = true
            });

            // 可选：配置 AOP 日志
            db.Aop.OnLogExecuting = (sql, pars) =>
            {
                Console.WriteLine(sql); // 输出 SQL
            };

            //只能是实体查询不能是匿名对象
            db.Aop.DataExecuted = (value, entityInfo) =>
            {
                if (entityInfo == null) return; // 跳过匿名对象

                var entityValue = entityInfo.EntityValue;
                if (entityValue == null) return;

                // 处理集合类型（如 ToList()）
                if (entityValue is IEnumerable entities)
                {
                    foreach (var entity in entities)
                    {
                        db.FillForeignData(entity);
                    }
                }
                // 处理单个实体（如 First()）
                else
                {
                    db.FillForeignData(entityValue);
                }
            };

            return db;
        });
    }
}